package cn.com.cifi.mars.service.impl;

import java.io.UnsupportedEncodingException;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Base64;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;

import cn.com.cifi.mars.bean.bo.PortalTodoBo;
import cn.com.cifi.mars.bean.dto.ProjectOrgDto;
import cn.com.cifi.mars.bean.vo.price.req.PriceApproveWarnCancelReqParam;
import cn.com.cifi.mars.bean.vo.price.req.PriceApproveWarnSaveReqParam;
import cn.com.cifi.mars.common.exception.MsgException;
import cn.com.cifi.mars.constant.CodeEnum;
import cn.com.cifi.mars.constant.Constants;
import cn.com.cifi.mars.constant.TodoOrgTypeEnum;
import cn.com.cifi.mars.constant.TodoTypeCodeEnum;
import cn.com.cifi.mars.constant.VersionIdTypeEnum;
import cn.com.cifi.mars.constant.WarnPossitionTypeEnum;
import cn.com.cifi.mars.constant.WhetherEnum;
import cn.com.cifi.mars.entity.ApprovalBill;
import cn.com.cifi.mars.entity.ApprovalWarning;
import cn.com.cifi.mars.entity.ApprovalWarningPosition;
import cn.com.cifi.mars.entity.ApprovalWarningSupervise;
import cn.com.cifi.mars.entity.common.IdmUser;
import cn.com.cifi.mars.mapper.mars.ApprovalBillMapper;
import cn.com.cifi.mars.mapper.mars.ApprovalWarningMapper;
import cn.com.cifi.mars.mapper.mars.ApprovalWarningSuperviseMapper;
import cn.com.cifi.mars.mapper.mars.IdmUserMapper;
import cn.com.cifi.mars.mapper.mars.ProjectMapper;
import cn.com.cifi.mars.mapper.mars.SysDictionaryMapper;
import cn.com.cifi.mars.service.ApprovalWarningSuperviseService;
import cn.com.cifi.mars.service.CommonService;
import cn.com.cifi.mars.service.PriceVersionGroupService;
import cn.com.cifi.mars.util.DateUtils;
import cn.com.cifi.mars.util.LocalDateTimeUtils;
import cn.com.cifi.mars.util.StrUtils;
import cn.com.cifi.mars.util.UUIDUtils;
import lombok.extern.slf4j.Slf4j;

/**
 * <p>
 * 货值预警督办表 服务实现类
 * </p>
 *
 * @author yyd
 * @since 2021-03-19
 */
@Slf4j
@Service
public class ApprovalWarningSuperviseServiceImpl extends ServiceImpl<ApprovalWarningSuperviseMapper, ApprovalWarningSupervise> implements ApprovalWarningSuperviseService {

	@Autowired
	ApprovalWarningMapper approvalWarningMapper;
	@Autowired
	ApprovalWarningSuperviseMapper approvalWarningSuperviseMapper;
	@Autowired
    ProjectMapper projectMapper;
	@Autowired
    IdmUserMapper idmUserMapper;
	@Autowired
	SysDictionaryMapper sysDictionaryMapper;
	@Autowired
	ApprovalBillMapper approvalBillMapper;
	@Autowired
    CommonService commonService;
	@Autowired
    PriceVersionGroupService priceVersionGroupService;

	@Value("${PORTAL_SYSCODE}")
	private String systemCode;
	
	@Value("${view_approved_url}")
	private String url;
	
	@Value("${warning_supervise_pc_url}")
	private  String warningSupervisePcUrl;
	
	@Value("${warning_supervise_app_url}")
	private String  warningSuperviseAppUrl;
	
	@Value("${PORTAL_SYSCODE}")
	private String sysCode;
	
	@Override
	public void sendWarningSupervise(String billId,Integer eventType) {
		ApprovalWarning approvalWarning = approvalWarningMapper.selectByBillId(billId);
		if(approvalWarning != null) {
			//生成集团审批版货值
			if(eventType.intValue() == Constants.FOUR) {
				if(approvalWarning.getWarnFlag().intValue() == WhetherEnum.YES.getKey() && approvalWarning.getIsPresident().intValue() == WhetherEnum.YES.getKey()) {
					priceVersionGroupService.generatePriceVersionGroup(approvalWarning.getProjectId(), approvalWarning.getBillId(),approvalWarning.getIsPresident());
					return;
				}else if(approvalWarning.getWarnFlag().intValue() == WhetherEnum.YES.getKey() && approvalWarning.getConfirmFlag().intValue() == WhetherEnum.YES.getKey()) {
					sendWarningTodo(approvalWarning,eventType);
				}
				priceVersionGroupService.generatePriceVersionGroup(approvalWarning.getProjectId(), approvalWarning.getBillId(),approvalWarning.getIsPresident());
			}else {
				if(approvalWarning.getWarnFlag().intValue() == WhetherEnum.YES.getKey() ) {
					sendWarningTodo(approvalWarning,eventType);
				}
			}
		}
		
	}
	
	public void sendWarningTodo(ApprovalWarning approvalWarning,Integer eventType) {
		String projectId = approvalWarning.getProjectId();
		String content = approvalWarning.getContent();
		List<ApprovalWarningPosition> warningPositionList = approvalWarningMapper.selectWarningPosition();
		if(eventType.intValue() == Constants.THREE) {
			//非集团高管预警
			sendWarningTodo(approvalWarning, projectId, content, warningPositionList);
		}else {
			try {
				//集团高管预警
				sendGroupWarningTodo(approvalWarning, projectId, content, warningPositionList);
			} catch (Exception e) {
				e.printStackTrace();
			}
			//督办预警
			sendWarningSuperviseTodo(approvalWarning, projectId, content, warningPositionList);
			
		}
	}

	private void sendWarningTodo(ApprovalWarning approvalWarning, String projectId, String content,
			List<ApprovalWarningPosition> warningPositionList) {
		ProjectOrgDto org = projectMapper.selectProjectParentData(projectId);
		String groupId = "";
		String regionId ="";
		String cityId ="";
		String projectName ="";
		if(org != null) {
			groupId = org.getGroupId();
			regionId=org.getRegionId();
			cityId=org.getCityId();
			projectName = org.getProjectName();
		}
		StringBuilder instanceIds = new StringBuilder();
		PortalTodoBo doorTodoBo=new PortalTodoBo();
		doorTodoBo.setTodoTypeCode(TodoTypeCodeEnum.WARNING_SUPERVISE.getKey());
		doorTodoBo.setVersionIdType(VersionIdTypeEnum.PRICE_VALUE.getKey());
		doorTodoBo.setOrgType(TodoOrgTypeEnum.FOUR.getKey());
		doorTodoBo.setGroupId(groupId);
		doorTodoBo.setRegionId(regionId);
		doorTodoBo.setCityId(cityId);
		doorTodoBo.setProjectId(projectId);
		//非集团高管人员
		List<IdmUser> userList = getWarningTodoUser(groupId,regionId,warningPositionList);
		if(CollectionUtils.isNotEmpty(userList)) {
			doorTodoBo.setTitle("【货值审批预警-审批提交】 "+projectName);
			doorTodoBo.setContent(content);
			for(IdmUser user : userList) {
				String instanceId = commonService.sendPortalTodo("", doorTodoBo, user);
				instanceIds.append(instanceId).append(";");
			}
			approvalWarning.setTaskId(instanceIds.toString());
			approvalWarning.setBillUrl(prepareBillUrl(approvalWarning.getBillId()));
			approvalWarningMapper.updateById(approvalWarning);
		}
	}

	private void sendGroupWarningTodo(ApprovalWarning approvalWarning, String projectId, String content,
			List<ApprovalWarningPosition> warningPositionList) {
		ProjectOrgDto org = projectMapper.selectProjectParentData(projectId);
		String groupId = "";
		String regionId ="";
		String cityId ="";
		String projectName ="";
		if(org != null) {
			groupId = org.getGroupId();
			regionId=org.getRegionId();
			cityId=org.getCityId();
			projectName = org.getProjectName();
		}
		StringBuilder instanceIds = new StringBuilder();
		PortalTodoBo doorTodoBoTwo=new PortalTodoBo();
		doorTodoBoTwo.setTodoTypeCode(TodoTypeCodeEnum.WARNING_SUPERVISE.getKey());
		doorTodoBoTwo.setVersionIdType(VersionIdTypeEnum.PRICE_VALUE.getKey());
		doorTodoBoTwo.setOrgType(TodoOrgTypeEnum.FOUR.getKey());
		doorTodoBoTwo.setGroupId(groupId);
		doorTodoBoTwo.setRegionId(regionId);
		doorTodoBoTwo.setCityId(cityId);
		doorTodoBoTwo.setProjectId(projectId);
		//集团高管人员
		instanceIds.append(approvalWarning.getTaskId());
		List<IdmUser> groupUserList = getGroupWarningTodoUser(groupId,regionId,warningPositionList);
		if(CollectionUtils.isNotEmpty(groupUserList)) {
			doorTodoBoTwo.setTitle("【货值审批预警-审批完成】 "+projectName);
			doorTodoBoTwo.setContent(content);
			for(IdmUser user : groupUserList) {
				String instanceId = commonService.sendPortalTodo("", doorTodoBoTwo, user);
				instanceIds.append(instanceId).append(";");
			}
			approvalWarning.setTaskId(instanceIds.toString());
			approvalWarning.setBillUrl(prepareBillUrl(approvalWarning.getBillId()));
			approvalWarningMapper.updateById(approvalWarning);
		}
	}

	private void sendWarningSuperviseTodo(ApprovalWarning approvalWarning, String projectId, String content,
			List<ApprovalWarningPosition> warningPositionList) {
		ProjectOrgDto org = projectMapper.selectProjectParentData(projectId);
		String groupId = "";
		String regionId ="";
		String cityId ="";
		String projectName ="";
		if(org != null) {
			groupId = org.getGroupId();
			regionId=org.getRegionId();
			cityId=org.getCityId();
			projectName = org.getProjectName();
		}
		PortalTodoBo doorTodoBoThree = new PortalTodoBo();
		doorTodoBoThree.setTodoTypeCode(TodoTypeCodeEnum.WARNING_SUPERVISE.getKey());
		doorTodoBoThree.setVersionIdType(VersionIdTypeEnum.PRICE_VALUE.getKey());
		doorTodoBoThree.setOrgType(TodoOrgTypeEnum.FOUR.getKey());
		doorTodoBoThree.setGroupId(groupId);
		doorTodoBoThree.setRegionId(regionId);
		doorTodoBoThree.setCityId(cityId);
		doorTodoBoThree.setProjectId(projectId);
		String  uniqIdString = systemCode+System.currentTimeMillis();
		List<IdmUser> userList = getWarningSuperviseUser(regionId,warningPositionList);
		if(CollectionUtils.isNotEmpty(userList)) {
			doorTodoBoThree.setTitle("【货值风险专项质询下发确认】 "+projectName);
			doorTodoBoThree.setContent(content);
			doorTodoBoThree.setMobileTaskUrl(warningSuperviseAppUrl);
			doorTodoBoThree.setPcTaskUrl(warningSupervisePcUrl);
			String instanceId = commonService.sendTodoMsg("", doorTodoBoThree,userList);
			saveApprovalWarningSupervise(regionId,instanceId,approvalWarning,warningPositionList,uniqIdString);
		}
	}
	
	private void saveApprovalWarningSupervise(String regionId,String instanceId, ApprovalWarning approvalWarning,List<ApprovalWarningPosition> warningPositionList,String  uniqIdString) {
		ApprovalWarningPosition fillObj = warningPositionList.stream().filter(x-> x.getType().equals(WarnPossitionTypeEnum.INFORMANT.getKey())).collect(Collectors.toList()).get(0);
		ApprovalWarningPosition superviseObj = warningPositionList.stream().filter(x-> x.getType().equals(WarnPossitionTypeEnum.SUPERVISE_BY.getKey())).collect(Collectors.toList()).get(0);
		ApprovalWarningSupervise warningSupervise = new ApprovalWarningSupervise();
		warningSupervise.setId(UUIDUtils.create());
		warningSupervise.setBillId(approvalWarning.getBillId());
		warningSupervise.setWarningId(approvalWarning.getId());
		warningSupervise.setTaskId(instanceId);
		warningSupervise.setProjectId(approvalWarning.getProjectId());
		warningSupervise.setFillAccount(fillObj.getPositionNum());
		warningSupervise.setFillName(fillObj.getPositionName());
		warningSupervise.setSuperviseAccount(superviseObj.getPositionNum());
		warningSupervise.setSuperviseName(superviseObj.getPositionName());
		warningSupervise.setBeSuperviseAccount(getBeSupervise(regionId,warningPositionList).get("account"));
		warningSupervise.setBeSuperviseName(getBeSupervise(regionId,warningPositionList).get("usercn"));
		warningSupervise.setPriority("重要紧急");
		warningSupervise.setStandard("以汇报结果会议纪要为准");
		warningSupervise.setTaskSource("供销存系统");
		warningSupervise.setHostFunction("营销");
		warningSupervise.setBackPeriod("按天");
		warningSupervise.setBackPeriodCount("3");
		warningSupervise.setFinishTime(LocalDateTime.now().plusDays(14));
		warningSupervise.setBillUrl(prepareBillUrl(approvalWarning.getBillId()));
		warningSupervise.setSuperviseUrl(warningSupervisePcUrl+instanceId+"&userId=");
		warningSupervise.setCreateBy(Constants.SYS);
		warningSupervise.setCreateTime(LocalDateTime.now());
		warningSupervise.setUniqId(uniqIdString);
		approvalWarningSuperviseMapper.insert(warningSupervise);
	}
	
	/**
	 * 审批URL
	 * @return
	 */
	private String prepareBillUrl(String billId) {
		String resultUrl = "";
		ApprovalBill bill = approvalBillMapper.selectApprovalBillByKey(billId);
		if(bill != null) {
			JSONObject instObject = new JSONObject();
            String instId = bill.getInstanceId();
            String taskId = bill.getTaskId();
            instObject.put("proInstId",instId);
            if(StrUtils.isNotEmpty(taskId)) {
            	instObject.put("taskId",taskId);
            }
            instObject.put("sysCode",sysCode);
            try {
                String encode = Base64.getEncoder().encodeToString(instObject.toString().getBytes("utf-8"));
                resultUrl = url+encode;
            } catch (UnsupportedEncodingException e) {
                log.error("###### errorMsg: ", e);
            }
		}
		return resultUrl;
	}

	/**
	 * 预警督办确认待办接收人
	 * @param regionId 区域ID
	 * @param warningPositionList 标准岗
	 * @return
	 */
	private List<IdmUser> getWarningSuperviseUser(String regionId,List<ApprovalWarningPosition> warningPositionList) {
		List<ApprovalWarningPosition> list = warningPositionList.stream().filter(x-> x.getType().equals(WarnPossitionTypeEnum.WARN_CONFIRM.getKey())).collect(Collectors.toList());
		List<String> positionGroupIds = new ArrayList<>();
		if(CollectionUtils.isNotEmpty(list)) {
			list.forEach(x->{
				positionGroupIds.add(x.getPositionNum());
			});
		}
		List<IdmUser> userList = idmUserMapper.selectRegionUser(positionGroupIds,regionId);
		return userList;
	}
	
	/**
	 * 预警待办接收人
	 * @param groupId 集团ID
	 * @param regionId 区域ID
	 * @param warningPositionList 标准岗
	 * @return
	 */
	private List<IdmUser> getWarningTodoUser(String groupId,String regionId,List<ApprovalWarningPosition> warningPositionList) {
		List<ApprovalWarningPosition> list = warningPositionList.stream().filter(x-> x.getType().equals(WarnPossitionTypeEnum.WARN_RECEIVE.getKey())).collect(Collectors.toList());
		List<String> rPositionGroupIds = new ArrayList<>();
		List<String> gPositionGroupIds = new ArrayList<>();
		List<String> userIds = new ArrayList<>();
		if(CollectionUtils.isNotEmpty(list)) {
			list.forEach(x->{
				if(x.getLevel().equals("个人")) {
					userIds.add(x.getPositionNum());
				}else if(x.getLevel().equals("区域")) {
					rPositionGroupIds.add(x.getPositionNum());
				}else {
					gPositionGroupIds.add(x.getPositionNum());
				}
			});
		}
		List<IdmUser> userList = idmUserMapper.selectRegionPrincipal(rPositionGroupIds,gPositionGroupIds,regionId,groupId);
		return userList;
	}
	
	/**
	 * 预警待办接收人
	 * @param groupId 集团ID
	 * @param regionId 区域ID
	 * @param warningPositionList 标准岗
	 * @return
	 */
	private List<IdmUser> getGroupWarningTodoUser(String groupId,String regionId,List<ApprovalWarningPosition> warningPositionList) {
		List<IdmUser> userList = new ArrayList<>();
		List<ApprovalWarningPosition> list = warningPositionList.stream().filter(x-> x.getType().equals(WarnPossitionTypeEnum.WARN_RECEIVE_GROUP.getKey())).collect(Collectors.toList());
		List<String> gPositionGroupIds = new ArrayList<>();
		List<String> rPositionGroupIds = new ArrayList<>();
		if(CollectionUtils.isNotEmpty(list)) {
			list.forEach(x->{
				if(x.getLevel().equals("区域")) {
					rPositionGroupIds.add(x.getPositionNum());
				}else {
					gPositionGroupIds.add(x.getPositionNum());
				}
			});
		}
		
		if(CollectionUtils.isNotEmpty(gPositionGroupIds)) {
			if(CollectionUtils.isNotEmpty(rPositionGroupIds)) {
				userList = idmUserMapper.selectRegionPrincipal(rPositionGroupIds,gPositionGroupIds,regionId,groupId);
			}else {
				userList = idmUserMapper.selectGroupPrincipal(gPositionGroupIds,groupId);
			}
		}
		return userList;
	}
	/**
	 * 保存意见
	 */
	@Override
	@Transactional
	public synchronized void  saveSuperviseInfo(IdmUser user, PriceApproveWarnSaveReqParam param) {
		if(param != null) {
			ApprovalWarningSupervise warningSupervise = approvalWarningSuperviseMapper.selectByTaskId(param.getTaskId());
			warningSupervise.setMarketingState(param.getMarketingSuggest());
			warningSupervise.setMarketingOpinionDesc(param.getMarketingOpinionDesc());
			warningSupervise.setOperationState(param.getOperationSuggest());
			warningSupervise.setOperationOpinionDesc(param.getOperationOpinionDesc());
			if(param.getPosition().equals("marketing")) {
				warningSupervise.setMarketingBy(user.getAlias());
			}else {
				warningSupervise.setOperationBy(user.getAlias());
			}
			warningSupervise.setBackPeriod(param.getFeedbackLoop());
			warningSupervise.setPriority(param.getPriority());
			warningSupervise.setFinishTime(LocalDateTimeUtils.strToDate(param.getFinishTime(),DateTimeFormatter.ofPattern(DateUtils.DATE_FULL_STR)));
			warningSupervise.setStandard(param.getCompletionCriteria());
			warningSupervise.setStandardDesc(param.getCompletionCriteriaDesc());
			warningSupervise.setFinishAsk(param.getFinishAsk());
			warningSupervise.setUpdateBy(user.getAlias());
			warningSupervise.setUpdateTime(LocalDateTime.now());
			approvalWarningSuperviseMapper.updateById(warningSupervise);
		}
		
	}

	/**
	 * 取消质询
	 */
	@Override
	@Transactional
	public void cancelSupervise(IdmUser user, PriceApproveWarnCancelReqParam param) {
		if(param != null) {
			ApprovalWarningSupervise warningSupervise = approvalWarningSuperviseMapper.selectByTaskId(param.getTaskId());
            if(warningSupervise.getIsSend() != null && warningSupervise.getIsSend().intValue() == 1) {
                CodeEnum.INTERNAL_ERROR.setMessage("督办已创建，不允许处理无需质询");
                    throw new MsgException(CodeEnum.INTERNAL_ERROR);
            }
			
			if(StrUtils.isEmpty(warningSupervise.getMarketingState()) || StrUtils.isEmpty(warningSupervise.getMarketingOpinionDesc())) {
				CodeEnum.INTERNAL_ERROR.setMessage("营销意见未反馈");
	   		 	throw new MsgException(CodeEnum.INTERNAL_ERROR);
			}
			warningSupervise.setCancelDesc(param.getCancelDesc());
			warningSupervise.setUpdateBy(user.getAlias());
			warningSupervise.setUpdateTime(LocalDateTime.now());
			approvalWarningSuperviseMapper.updateById(warningSupervise);
		}
	}
	
	/**
	 * 被督办人
	 * @param regionId 区域
	 * @param warningPositionList 标准岗
	 * @return
	 */
	private Map<String, String> getBeSupervise(String regionId,List<ApprovalWarningPosition> warningPositionList) {
		String account="";
		String usercn="";
		Map<String, String> map = new HashMap<String, String>();
		List<ApprovalWarningPosition> list = new  ArrayList<>();
		if(regionId.equals("10270000")) {
			list = warningPositionList.stream().filter(x-> WarnPossitionTypeEnum.HOST_BY_SD.getKey().equals(x.getType())).collect(Collectors.toList());
		}else {
			list = warningPositionList.stream().filter(x-> WarnPossitionTypeEnum.HOST_BY.getKey().equals(x.getType())).collect(Collectors.toList());
		}
		
		List<String> positionGroupIds = new ArrayList<>();
		list.forEach(x->{
			positionGroupIds.add(x.getPositionNum());
		});
		List<IdmUser> userList = idmUserMapper.selectRegionUser(positionGroupIds,regionId);
		if(CollectionUtils.isNotEmpty(userList)) {
			account = userList.get(0).getAlias();
			usercn = userList.get(0).getUsercn();
		}
		map.put("account", account);
		map.put("usercn", usercn);
		return map;
	}

}
